package com.miyake.dsp.osa.ui;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.border.TitledBorder;
import javax.swing.filechooser.FileFilter;

import com.miyake.dsp.osa.ChannelProperty;
import com.miyake.dsp.osa.WdmProperty;

public abstract class WdmSettingUI extends JFrame {
	/**
	 * 
	 */
	private static final long serialVersionUID = 4005630248387716627L;
	private static int WIDGET_HEIGHT = 24;
	private JTextField spacingText;
	private JTextField peaksText;
	private JTextField pointText;
	private JTextField inFileText;
	private JTextField outFileText;
	private JCheckBox gainCheck;
	private JCheckBox aseCheck;
//	private Map<String, String> fileMap = new HashMap<String, String>();
//	private Map<String, String> dirMap = new HashMap<String, String>();
	private JCheckBox checkPreset;
	private MyComboBox comboFile;
	private MyComboBox comboDir;
	private JTextField gainText;
	private JTextField aseText;
	private JCheckBox gainFlatCheck;
	private JCheckBox aseFlatCheck;
	private JCheckBox whiteCheck;
	private JTextField whiteText;
	
	JFileChooser filechooser;
	private JCheckBox randomCheck;
	private JTextField textCenter;
	private JTextField textSpan;
	private JRadioButton simpleRadio;
	private JRadioButton customRadio;
	private ChannelProperty channelProperty;
	
	
	public abstract void onSetClick(WdmProperty prop);
	
	class MyComboBox extends JComboBox {
		private Map<String, String> map = new HashMap<String, String>();
		public void addItem(String item, String value) {
			this.addItem(item);
			map.put(item, value);
		}
		public String getSelecteValue() {
			return map.get(getSelectedItem());
		}
	};
	
	public WdmSettingUI(WdmProperty prop) {
		initialize(prop);
	}
	
	private void initialize(WdmProperty prop) {
		channelProperty = prop.getChannelProperty();
		this.setTitle("WDM Source Setting");
		this.setSize(new Dimension(500, 350));
		Container c = this.getContentPane();
		
		c.setLayout(new FlowLayout());
		c.add(createPreset(prop.isPreset()));
		c.add(createPresetData(prop.getResolution(), prop.getVbw()));
		c.add(createInFile(prop.getInFile()));
		c.add(createOutFile(prop.getOutFile()));
//		c.add(createPeakCount(prop.getPeakCount()));
		c.add(createSelection(prop.isCustom()));
		c.add(createSimpleData(prop.getSpacing(), prop.getPoints()));

		c.add(createEditorButton());
		c.add(createGain(prop.isGain(), prop.getGainValue(), prop.isGainFlat()));
		c.add(createAse(prop.isAse(), prop.getAseValue(), prop.isAseFlat()));
		c.add(createWhiteNoise(prop.isWhiteNoise(), prop.getWhiteNoiseValue()));
//		c.add(createWavelength(prop.getCenter(), prop.getSpan()));
		
		c.add(createSetButton());
	}

	private Component createSelection(boolean custom) {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("Select"));
		simpleRadio = new JRadioButton("Array");
		customRadio = new JRadioButton("Custom");
		p.add(simpleRadio);
		p.add(customRadio);
		simpleRadio.setSelected(!custom);
		customRadio.setSelected(custom);
		simpleRadio.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				customRadio.setSelected(!simpleRadio.isSelected());
			}
		});
		customRadio.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				simpleRadio.setSelected(!customRadio.isSelected());
			}
		});
		
		
		return p;
	}

	private Component createEditorButton() {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("Custom"));
		JButton button = new JButton();
		button.setText("Signal Editor");
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				new SignalEditorUI(channelProperty) {
					@Override
					public void onSet(ChannelProperty newProperty) {
						channelProperty = newProperty;
						onSetClick(createPropertyObject());
					}
				}.setVisible(true);
			}
		});
		p.add(button);
		return p;
	}
	private Component createWavelength(double center, double span) {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("Wavelength"));
		p.add(new JLabel("Center"));
		textCenter = new JTextField(String.valueOf(center));
		textCenter.setPreferredSize(new Dimension(50, WIDGET_HEIGHT));
		p.add(textCenter);
		p.add(new JLabel("Span"));
		textSpan = new JTextField(String.valueOf(span));
		textSpan.setPreferredSize(new Dimension(50, WIDGET_HEIGHT));
		p.add(textSpan);
		return p;
	}
	
	private Component createWhiteNoise(boolean whiteNoise,
			double whiteNoiseValue) {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("White Noise"));
		
		whiteCheck = new JCheckBox("On");
		whiteCheck.setSelected(whiteNoise);
		p.add(whiteCheck);
		whiteCheck.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				updateWhiteNoiseWidgetStatus();
			}
			
		});
		whiteText = new JTextField();
		whiteText.setText(String.valueOf(whiteNoiseValue));
		whiteText.setPreferredSize(new Dimension(40, WIDGET_HEIGHT));
		p.add(whiteText);	
		p.add(new JLabel("uW"));
		
		updateWhiteNoiseWidgetStatus();
		return p;
	}
	private Component createPreset(boolean b) {
		checkPreset = new JCheckBox("Preset Data");
		checkPreset.setSelected(b);
		checkPreset.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				updatePresetWidgetStatus();
			}
		});
		updatePresetWidgetStatus();
		return checkPreset;
	}
	private Component createPresetData(String res, String vbw) {
		JPanel p = new JPanel();
		
		comboFile = new MyComboBox();
		comboFile.addItem("0.03nm", "RES0.03.csv");
		comboFile.addItem("0.05nm", "RES0.05.csv");
		comboFile.addItem("0.07nm", "RES0.07.csv");
		comboFile.addItem("0.1nm", "RES0.1.csv");
		comboFile.addItem("0.2nm", "RES0.2.csv");
		comboFile.addItem("0.5nm", "RES0.5.csv");
		comboFile.addItem("1.0nm", "RES1.0.csv");
		comboFile.setSelectedItem(res);
		

		
		comboDir = new MyComboBox();
		comboDir.addItem("1MHz", "VBW1MHz");
		comboDir.addItem("100kHz", "VBW100kHz");
		comboDir.addItem("10kHz", "VBW10kHz");
		comboDir.addItem("1kHz", "VBW1kHz");
		comboDir.setSelectedItem(vbw);
		
		if (!checkPreset.isSelected()) {
			comboFile.setEnabled(false);
			comboDir.setEnabled(false);
		}
		p.add(comboFile);
		p.add(comboDir);
		
		return p;
	}
	private Component createAse(boolean ase, double value, boolean flat) {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("ASE"));
		
		aseCheck = new JCheckBox("On");
		aseCheck.setSelected(ase);
		p.add(aseCheck);
		
		aseCheck.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				updateAseWidgetStatus();
			}
			
		});
		aseText = new JTextField();
		aseText.setText(String.valueOf(value));
		aseText.setPreferredSize(new Dimension(40, WIDGET_HEIGHT));
		p.add(aseText);	
		p.add(new JLabel("uW"));
		
		aseFlatCheck = new JCheckBox("Flat");
		aseFlatCheck.setSelected(flat);
		p.add(aseFlatCheck);
		updateAseWidgetStatus();
		return p;
	}
	
	private Component createGain(boolean gain, double value, boolean flat) {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("Gain"));
		gainCheck = new JCheckBox("On");
		gainCheck.setSelected(gain);
		p.add(gainCheck);
		
		gainCheck.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				updateGainWidgetStatus();
			}
			
		});
		gainText = new JTextField();
		gainText.setPreferredSize(new Dimension(40, WIDGET_HEIGHT));
		gainText.setText(String.valueOf(value));
		p.add(gainText);
		p.add(new JLabel("dB"));
		
		gainFlatCheck = new JCheckBox("Flat");
		gainFlatCheck.setSelected(flat);
		p.add(gainFlatCheck);
		updateGainWidgetStatus();
		return p;
	}

	private Component createSetButton() {
		JButton close = new JButton("Set");
		close.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				WdmProperty prop = createPropertyObject();
				prop.setChannelProperty(channelProperty);
				onSetClick(prop);
			}
			
		});
		return close;
	}

	private Component createSimpleData(double spacing, int points) {
		JPanel p = new JPanel();
		p.setBorder(new TitledBorder("Array"));
		spacingText = new JTextField();
		spacingText.setPreferredSize(new Dimension(50, WIDGET_HEIGHT));
		spacingText.setText(String.valueOf(spacing));
		p.add(new JLabel("Spacing"));
		p.add(spacingText);
		p.add(new JLabel("nm"));
		
		pointText = new JTextField();
		pointText.setPreferredSize(new Dimension(50, WIDGET_HEIGHT));
		pointText.setText(String.valueOf(points));
		p.add(new JLabel("Sampling Points"));
		p.add(pointText);
		
		return p;
	}

	private Component createPeakCount(int peakCount) {
		JPanel p = new JPanel();
		peaksText = new JTextField();
		peaksText.setPreferredSize(new Dimension(200, WIDGET_HEIGHT));
		peaksText.setText(String.valueOf(peakCount));
		p.add(new JLabel("Peak Count"));
		p.add(peaksText);
		return p;
	}

	private Component createInFile(String inFile) {
		JPanel p = new JPanel();
		inFileText = new JTextField();
		inFileText.setPreferredSize(new Dimension(400, WIDGET_HEIGHT));
		inFileText.setText(inFile);
		p.add(new JLabel("In"));
		p.add(inFileText);
		JButton openButton = new JButton("...");
		openButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String s;
				if ((s = showOpenDialog()) != null) {
					inFileText.setText(s);
				}
			}
		});
		p.add(openButton);
		return p;
	}

	protected String showOpenDialog() {
		if (filechooser == null) { 
			filechooser = new JFileChooser();
			filechooser.addChoosableFileFilter(new FileFilter() {
				@Override
				public boolean accept(File f) {
					return f.getName().endsWith("csv");
				}

				@Override
				public String getDescription() {
					return "MS9740A CSV";
				}
				
			});

		}
		
		
		int selected = filechooser.showOpenDialog(this);
		if (selected == JFileChooser.APPROVE_OPTION){
		  return filechooser.getSelectedFile().getAbsolutePath();

		  
		}else if (selected == JFileChooser.CANCEL_OPTION){
		}else if (selected == JFileChooser.ERROR_OPTION){
		}
		
		return null;
	}
	private Component createOutFile(String outFile) {
		JPanel p = new JPanel();
		outFileText = new JTextField();
		outFileText.setPreferredSize(new Dimension(400, WIDGET_HEIGHT));
		outFileText.setText(outFile);
		p.add(new JLabel("Out"));
		p.add(outFileText);
		JButton openButton = new JButton("...");
		openButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				String s;
				if ((s = showOpenDialog()) != null) {
					outFileText.setText(s);
				}
			}
		});
		p.add(openButton);
		return p;
	}

	private void updateGainWidgetStatus() {
		gainText.setEnabled(gainCheck.isSelected());
		gainFlatCheck.setEnabled(gainCheck.isSelected());
	}
	private void updateAseWidgetStatus() {
		aseText.setEnabled(aseCheck.isSelected());
		aseFlatCheck.setEnabled(aseCheck.isSelected());
	}
	private void updatePresetWidgetStatus() {
		if (inFileText != null) {
			inFileText.setEnabled(!checkPreset.isSelected());
			outFileText.setEnabled(!checkPreset.isSelected());
			comboFile.setEnabled(checkPreset.isSelected());
			comboDir.setEnabled(checkPreset.isSelected());
		}
	}
	private void updateWhiteNoiseWidgetStatus() {
		whiteText.setEnabled(whiteCheck.isSelected());
	}

	private WdmProperty createPropertyObject() {
		WdmProperty prop = new WdmProperty();
		if (checkPreset.isSelected()) {
			prop.setInFile("data\\" + comboDir.getSelecteValue() + "\\" + comboFile.getSelecteValue());
			prop.setOutFile("data\\" + comboDir.getSelecteValue() + "\\" + comboFile.getSelecteValue());
		}
		else {
			prop.setInFile(inFileText.getText());
			prop.setOutFile(outFileText.getText());
		}

		prop.setSpacing(Double.valueOf(spacingText.getText()));
		prop.setPoints(Integer.valueOf(pointText.getText()));
		prop.setGain(gainCheck.isSelected());
		prop.setGainValue(Double.valueOf(gainText.getText()));
		prop.setGainFlat(gainFlatCheck.isSelected());
		prop.setAse(aseCheck.isSelected());
		prop.setAseValue(Double.valueOf(aseText.getText()));
		prop.setAseFlat(aseFlatCheck.isSelected());
		prop.setWhiteNoiseValue(Double.valueOf(whiteText.getText()));
		prop.setWhiteNoise(whiteCheck.isSelected());
		prop.setResolution((String)comboFile.getSelectedItem());
		prop.setVbw((String)comboDir.getSelectedItem());
		prop.setPreset(checkPreset.isSelected());
		prop.setCustom(customRadio.isSelected());
		
		prop.setChannelProperty(channelProperty);
		return prop;
	}
}
